<template>
  <template v-if="props.uploadType != UploadTypeEnum.image">
    <a-upload
      v-if="props.uploadMode === 'defaults'"
      v-model:file-list="fileList"
      name="file"
      :action="action"
      :headers="headers"
      :maxCount="props.uploadNumber"
      @change="handleChange"
      :disabled="disabled"
      @preview="onFilePreview"
    >
      <a-button :disabled="buttonDisabled">
        <upload-outlined />
        上传
      </a-button>
    </a-upload>

    <a-upload-dragger
      v-if="props.uploadMode === 'drag'"
      v-model:fileList="fileList"
      name="file"
      :multiple="true"
      :action="action"
      :headers="headers"
      :maxCount="props.uploadNumber"
      @change="handleChange"
      :disabled="disabled"
      @preview="onFilePreview"
    >
      <p class="ant-upload-drag-icon">
        <inbox-outlined />
      </p>
      <p class="ant-upload-text">单击或拖动文件到此区域上传</p>
      <p class="ant-upload-hint"></p>
    </a-upload-dragger>
  </template>
  <div v-if="props.uploadType === UploadTypeEnum.image">
    <a-upload
      :listType="listType"
      accept="image/*"
      v-model:file-list="fileList"
      name="file"
      :action="action"
      :headers="headers"
      :maxCount="props.uploadNumber"
      @change="handleChange"
      :disabled="disabled"
      @preview="handlePreview"
    >
      <div v-if="!buttonDisabled">
        <div v-if="listType == 'picture-card'">
          <LoadingOutlined v-if="loading" />
          <UploadOutlined v-else />
          <div class="ant-upload-text">上传</div>
        </div>
        <a-button v-if="listType == 'picture'" :disabled="disabled">
          <UploadOutlined />
          上传
        </a-button>
      </div>
    </a-upload>
    <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel()">
      <img alt="example" style="width: 100%" :src="previewImage" />
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { message } from 'ant-design-vue';
import { UploadTypeEnum, UploadStatus } from '@/enums/commonEnum';
import type { UploadChangeParam } from 'ant-design-vue';

const emit = defineEmits(['change', 'update:value']);
const headers = ref({});
const props = defineProps({
  value: {
    type: [String, Array],
  },
  uploadType: {
    type: String,
    default: UploadTypeEnum.all,
  },
  // 文件上传方式 defaults || drag
  uploadMode: {
    type: String,
    default: 'defaults',
    required: false,
  },
  // 上传数量
  uploadNumber: {
    type: Number,
    default: 1,
    required: false,
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  // 图片上传listType
  listType: {
    type: String,
    default: 'picture-card',
  },
  action: {
    type: String,
    default: '',
  },
});
const fileList = ref<any>([]);
//预览图
const previewImage = ref<string | undefined>('');
//预览框状态
const previewVisible = ref<boolean>(false);
const loading = ref();
// 是否达到了最大上传数量
const isMaxCount = computed(() => props.uploadNumber > 0 && fileList.value.length >= props.uploadNumber);
// 上传按钮是否禁用
const buttonDisabled = computed(() => {
  if (props.disabled === true) {
    return true;
  }
  if (isMaxCount.value === true) {
    return true;
  }
  return false;
});

watch(
  () => props.value,
  (val) => {
    if (Array.isArray(val)) {
      parseArrayValue(val);
    } else {
      val && parseArrayValue(JSON.parse(val));
    }
  },
  { immediate: true },
);
// 解析数组值
function parseArrayValue(array: Array<any>) {
  if (!array || array.length == 0) {
    fileList.value = [];
    return;
  }
  let list = [];
  for (const item of array) {
    list.push({
      uid: uidGenerator(),
      name: item.fileName,
      url: item.filePath,
      status: UploadStatus.done,
      response: { status: 'history', data: item.filePath },
    });
  }
  fileList.value = list;
}
function uidGenerator() {
  return '-' + parseInt(Math.random() * 10000 + 1 + '', 10);
}
// upload组件change事件
const handleChange = (info: UploadChangeParam) => {
  let fileListTemp = info.fileList;
  // 限制最大上传数
  if (props.uploadNumber > 0) {
    let count = fileListTemp.length;
    if (count >= props.uploadNumber) {
      let diffNum = props.uploadNumber - fileListTemp.length;
      if (diffNum >= 0) {
        fileListTemp = fileListTemp.slice(-props.uploadNumber);
      } else {
        return;
      }
    }
  }
  if (info.file.status === UploadStatus.done) {
    let successFileList = [];
    if (info.file.response && info.file.response.code === 200) {
      successFileList = fileListTemp.map((file) => {
        if (file.response) {
          file.url = file.response.data;
        }
        return file;
      });
    } else {
      successFileList = fileListTemp.filter((item) => {
        return item.uid != info.file.uid;
      });
      message.error(`${info.file.name} 上传失败。`);
    }
    fileListTemp = successFileList;
  } else if (info.file.status === UploadStatus.error) {
    message.error(`${info.file.name} 上传失败。`);
  }
  fileList.value = fileListTemp;
  if (info.file.status === UploadStatus.done || info.file.status === UploadStatus.removed) {
    let newFileList = [];
    for (const item of fileListTemp) {
      if (item.status === UploadStatus.done) {
        let fileJson = {
          fileName: item.name,
          filePath: item.response.data,
          fileSize: item.size,
        };
        newFileList.push(fileJson);
      } else {
        return;
      }
    }
    console.log('JSON.stringify(newFileList)', JSON.stringify(newFileList));
    emitValue(JSON.stringify(newFileList));
  }
};
// 通过DOM获取上传的文件
const uploadFileList = () => {
  if (fileList.value) {
    const result: any[] = [];
    // 只返回这些就够用了，其他基本用不到
    fileList.value.forEach((item: any) => {
      const obj = {
        name: item.name,
        type: item.type,
        size: item.size,
        url: item.response.data,
      };
      result.push(obj);
    });
    return result;
  } else {
    return [];
  }
};

// 预览文件
function onFilePreview(file: any) {
  window.open(file.url);
}
function handleCancel() {
  previewVisible.value = false;
}
/**
 * 预览图片
 */
function handlePreview(file: any) {
  previewImage.value = file.url || file.thumbUrl;
  previewVisible.value = true;
}
function emitValue(value: string) {
  emit('change', value);
  emit('update:value', value);
}

// 抛出这个获取文件列表的方法
defineExpose({
  uploadFileList,
});
</script>
